package util;

import model.Data;
import model.User;
import view.Card;
import view.Plant;
import view.SunFactory;
import view.Zombie;
import view.Car;

import javax.swing.*;

import dao.DataDaoImpl;
import dao.UserDaoImpl;

import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.List;

public class Controller {
	
	static int GAME_WIN = 3;
    static int GAME_LOSE = 2;
    static int GAME_PAUSE = 1;
    static int GAME_RUNNING = 0;
	
	
    private User user;
    private JLabel sunCount;
    private Frame frame;
    private SunFactory sunFactory;
    private Point p;
    private boolean gameOver;
    private TopPanel topPanel = new TopPanel();
    private ArrayList<Card> cardList;
    private ImageIcon preImg;
    private ImageIcon blurImg;
    private JLayeredPane layeredPane;
    private Card card;
    private List<ArrayList<Zombie>> zombieLists = new ArrayList<>();
    private List <Car> carList = new ArrayList<>();
    private Plant [][]plants = new Plant[5][9];
    private Rectangle lawnArea = new Rectangle(45,90,715,480);
    private Data data = new Data();
    private JLabel Shovel ;
    
    private int gameState;   
    
    public void setShovel(JLabel shovel) {
		Shovel = shovel;
	}

	public boolean isRunning() {
    	return gameState == GAME_RUNNING;
    }
    
    public boolean isWin() {
    	return gameState == GAME_WIN;
    }
    
    public boolean isLose() {
    	return gameState == GAME_LOSE;
    }
    
    public boolean isPause() {
    	return gameState == GAME_PAUSE;
    }
    
    public void setGameState(String gameState) {
		switch(gameState) {
			case "PAUSE":{
				this.gameState = GAME_PAUSE;
				break;
			}
			case "WIN":{
				this.gameState = GAME_WIN;
				break;
			}
			case "LOSE":{
				this.gameState = GAME_LOSE;
				break;
			}
			case "RUNNING":{
				this.gameState = GAME_RUNNING;
				break;
			}
		}
	}


	public Data getData() {
		return data;
	}

	public void setData(Data data) {
		this.data = data;
	}

	public ArrayList<Card> getCardList() {
		return cardList;
	}

	public void setGameOver(boolean gameOver) {
		this.gameOver = gameOver;
	}

	public boolean isNewGame(){
        return user.getGameProgress() == 0;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public User getUser() {
        return user;
    }

    public Plant[][] getPlants() {
        return plants;
    }

    public List<ArrayList<Zombie>> getZombieLists() {
        return zombieLists;
    }

    public void setPlants(Plant[][] plants) {
        this.plants = plants;
    }

    public void setFrame(Frame frame) {
        this.frame = frame;
    }

    public Frame getFrame() {
        return frame;
    }

    public void setZombieLists(List<ArrayList<Zombie>> zombieLists) {
        this.zombieLists = zombieLists;
    }

    public boolean isGameOver() {
        return gameOver;
    }
    
    public boolean loginExam(String admin, String pass) {
        List<User> userList = new UserDaoImpl().readUser();
        for( User user: userList) {
            if (user.getAdmin().equals(admin) && user.getPass().equals(pass))
                return true;
        }
        return false;
    }
    
    public boolean userExam(String admin) {
        List<User> userList = new UserDaoImpl().readUser();
        for( User user: userList) {
            if (user.getAdmin().equals(admin))
                return true;
        }
        return false;
    }
    
    public void plantDeath(Plant plant){
        int r = plant.getR();
        int c = plant.getC();
        System.out.println(plants[r][c].getName()+" is dead  ("+r+","+c+")");
        plants[r][c] = null;
    }

    public JLabel getSunCount() {
        return sunCount;
    }

    public JLayeredPane getLayeredPane() {
        return layeredPane;
    }

    public Point getP() {
        return topPanel.getMousePosition();
    }

    public void setP(Point p) {
        this.p = p;
    }

    public boolean isOnTheGrass(Point p){
        return lawnArea.contains(p);
    }

    public void getCard(Card card){
        this.card = card;
    }

    public void setPreImg(ImageIcon preImg) {
        this.preImg = preImg;
    }

	public void setBlurImg(ImageIcon blurImg) {
		this.blurImg = blurImg;
	}

    public SunFactory getSunFactory() {
        return sunFactory;
    }

	public List<Car> getCarList() {
		return carList;
	}

	public void setCarList(List<Car> carList) {
		this.carList = carList;
	}

	public void plant(String plantName, int r, int c){
        new MusicPlayer("audio\\plant.mp3").start();
        Plant newPlant = new Plant().getPlant(plantName);
        plants[r][c] = newPlant;
        newPlant.setController(this);
        newPlant.setR(r);
        newPlant.setC(c);
        newPlant.setVisible(true);
        newPlant.setBounds(45+c*80, 90+r*100,
                300, 300 );
        layeredPane.add(newPlant, new Integer(50));
        new Thread(newPlant).start();
    }
    

	public int getSun() {
    	return sunFactory.getSumsun();
    }
    
	class TopPanel extends JPanel{
		private static final long serialVersionUID = 1L;
		Graphics2D g2;
        private Point p;
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g2 = (Graphics2D) g;
            p = getP();
            if (p!=null){
                int c = (p.x-40)/80;
                int r = (p.y-90)/100;
                if (isOnTheGrass(p)&&plants[r][c]==null){
                    g2.drawImage(blurImg.getImage(),40+c*80, 90+r*100, this);
                }
                g2.drawImage(preImg.getImage(), p.x-35, p.y-40,
                        preImg.getIconWidth(), preImg.getIconWidth(),this);
            }
        }
        public void update(Graphics g) {
            Image offScreenImage = this.createImage(800, 600);
            Graphics gImage = offScreenImage.getGraphics();
            paint(gImage);
            if (p!=null){
                g.drawImage(offScreenImage, p.x-35, p.y-40, null);
            }
        }
    }

    public List<String> getMission(int level) throws IOException{
        List<String> list = new ArrayList<>();
        FileInputStream fis = new FileInputStream("level\\"+level+".txt");
        InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
        BufferedReader br = new BufferedReader(isr);
        String line = "";
        while ((line = br.readLine()) != null) {
            // 如果 t x t文件里的路径 不包含---字符串       这里是对里面的内容进行一个筛选
            if (line.lastIndexOf("---") < 0) {
                list.add(line);
            }
        }
        return list;
    }

    public boolean findZombie(int r, int c){
        List<Zombie> zombieList = zombieLists.get(r);
        for (Zombie zombie: zombieList){
            int zombieX = zombie.getX();
            if (zombieX<(690+new Random().nextInt(6))&&zombieX>=c*80){
                return true;
            }
        }
        return false;
    }

    class MyMouseListener extends MouseAdapter implements MouseMotionListener {
        private TopPanel topPanel;
        
        MyMouseListener(TopPanel topPanel){
            this.topPanel = topPanel;
        }
        
        public void mouseClicked(MouseEvent e) {
            Point p = getP();          
            
            if(preImg.getDescription().equals("img\\Shovel.png")) {          	
                int c = (p.x-40)/80;
                int r = (p.y-90)/100;
                if (plants[r][c]!=null){
                	plants[r][c].setVisible(false); 
                	plants[r][c]=null;            	
                }
                topPanel.setVisible(false);
                Shovel.setVisible(true);
                return;
            }          	         
            if (isOnTheGrass(p)){  //种植
                int c = (p.x-40)/80;
                int r = (p.y-90)/100;
                if (plants[r][c]!=null){
                    System.out.println("There is already a plant there");
                    return;
                }
                plant(card.getCardName(), r, c);
                sunFactory.setSumSun(sunFactory.getSumsun()-card.getPrice());
                sunCount.setText(""+sunFactory.getSumsun());
                checkCards();
            }else{
                card.picChange();
            }
            
            topPanel.setVisible(false);
        }
        public void mousePressed(MouseEvent e) {

        }
        public void mouseReleased(MouseEvent e) {

        }
        public void mouseEntered(MouseEvent e) {

        }
        public void mouseDragged(MouseEvent e) {

        }
        public void mouseMoved(MouseEvent e) {
            setP(e.getPoint());
            topPanel.repaint();
        }
        public void mouseExited(MouseEvent e) {

        }
    }

    public void blast(int r, int c, int range){
        Rectangle blastRange = new Rectangle(
                c*80-135, r*100-10, 230,300);
        for (List<Zombie> zombieList:zombieLists){
            for (Zombie zombie: zombieList){
                int y = zombie.getR() * 100 + 90;
                int x = zombie.getX();
                if (blastRange.contains(x,y)){
                    zombie.boomDie();
                }
            }
        }
    }

    public  JPanel getTopPanel() {
        return topPanel;
    }

    public void setSunFactory(SunFactory sunFactory) {
        this.sunFactory = sunFactory;
    }

    public void setSunCount(JLabel sunCount) {
        this.sunCount = sunCount;
    }

    public void setLayeredPane(JLayeredPane layeredPane) {
        this.layeredPane = layeredPane;
    }

    public void setCardList(ArrayList<Card> cardList) {
        this.cardList = cardList;
    }

    public Controller(){
        this.topPanel.addMouseMotionListener(new MyMouseListener(this.topPanel));
        this.topPanel.addMouseListener(new MyMouseListener(this.topPanel));
        this.topPanel.setVisible(false);
        this.gameState = GAME_RUNNING;
    }

    public void readData(User user) {
    	this.setUser(user);
    	//this.setData(new DataDaoImpl().readData(user));
    }
    
    public void checkCards(){
        for (Card card: cardList){
            card.check(Integer.parseInt(sunCount.getText()));
        }
    }
}
